<template>
  <a-modal v-model:open="deleteOpen" title="删除提示" ok-text="确认" cancel-text="取消" @ok="deleteOk">
    确认删除？
  </a-modal>
  <a-modal v-model:open="deleteConfirmOpen" title="删除提示" ok-text="确认" cancel-text="取消" @ok="deleteConfirmOk">
    有角色设置了该目录,确认删除？
  </a-modal>
  <a-modal v-model:open="addOpen" v-model:title="addModifyTitle" :footer="null" :afterClose="afterCloseModal">
    <a-form ref="formRef" :model="permission" :label-col="labelCol" :wrapper-col="wrapperCol" @finish="onFinish"
      :rules="permissionRules" @finishFailed="onFinishFailed">
      <input type="hidden" name="id" v-model="permission.id" />

      <a-form-item v-if="disabledFlag" label="一级目录" name="pid">
        <a-select label-in-value v-model:value="permission.pid" style="width: 120px" placeholder="请选择一级目录 "
          :options="firstMenu"></a-select>
      </a-form-item>
      <input v-else type="hidden" name="pid" v-model="permission.pid" />
      <a-form-item label="目录名称" name="permissionName">
        <a-input v-model:value="permission.permissionName" />
      </a-form-item>
      <a-form-item label="显示名称" name="displayName">
        <a-input v-model:value="permission.displayName" />
      </a-form-item>
      <a-form-item label="描述" name="description">
        <a-input v-model:value="permission.description" />
      </a-form-item>
      <a-form-item label="是否在菜单中显示" name="menuFlag">
        <a-switch v-model:checked="permission.menuFlag" name="accountNonExpired" />
      </a-form-item>
      <a-form-item v-if="disabledFlag" label="权限匹配字符串" name="patchString">
        <a-input v-model:value="permission.patchString" />
      </a-form-item>
      <a-form-item label="同级目录排序" name="orderNumber">
        <a-input v-model:value="permission.orderNumber" />
      </a-form-item>
      <a-form-item :wrapper-col="{ span: 14, offset: 4 }">
        <a-button type="primary" html-type="submit">保存</a-button>
        <a-button style="margin-left: 10px" @click="closeForm">关闭</a-button>
      </a-form-item>
    </a-form>
  </a-modal>
  <!-- 操作按钮区域 -->
  <div class="table-operator" style="margin:5px 0;border-top: 5px;float: left; ">
    <a-space v-if="operation == 7" wrap>
      <a-button @click="handleAddFirst" type="primary">增加一级目录</a-button>
      <a-button @click="handleAddSecond" type="primary">增加二级目录</a-button>
      <a-button @click="handleModify" type="primary">修改目录</a-button>
      <a-button @click="handleDelete" type="primary">删除目录</a-button>
    </a-space>
    <a-space v-else-if="operation == 6" wrap>
      <a-button @click="handleModify" type="primary">修改目录</a-button>
      <a-button @click="handleDelete" type="primary">删除目录</a-button>
    </a-space>
    <a-space v-else-if="operation == 5" wrap>
      <a-button @click="handleAddFirst" type="primary">增加一级目录</a-button>
      <a-button @click="handleAddSecond" type="primary">增加二级目录</a-button>
      <a-button @click="handleDelete" type="primary">删除目录</a-button>
    </a-space>
    <a-space v-else-if="operation == 4" wrap>
      <a-button @click="handleDelete" type="primary">删除目录</a-button>
    </a-space>
    <a-space v-else-if="operation == 3" wrap>
      <a-button @click="handleAddFirst" type="primary">增加一级目录</a-button>
      <a-button @click="handleAddSecond" type="primary">增加二级目录</a-button>
      <a-button @click="handleModify" type="primary">修改目录</a-button>
    </a-space>
    <a-space v-else-if="operation == 2" wrap>
      <a-button @click="handleModify" type="primary">修改目录</a-button>
    </a-space>
    <a-space v-else-if="operation == 1" wrap>
      <a-button @click="handleAddFirst" type="primary">增加一级目录</a-button>
      <a-button @click="handleAddSecond" type="primary">增加二级目录</a-button>
    </a-space>
  </div>
  <a-table :columns="columns" :pagination="false" :data-source="tabledata" :customRow="rowClick"
    :row-selection="rowSelection" :scroll="{ y: 550 }" sticky />
</template>
<script lang="ts" setup>

import { ref, Ref, reactive, UnwrapRef, onMounted } from 'vue';
import { message } from 'ant-design-vue';
import http from '@/utils/http';
import showErrors from '@/utils/publicfunction';
import store from '@/store';
import type { StateAll } from '@/store';
//一级目录的id和显示名称，因为要用到select组件，所以需要
interface optionIntface {
  value: number;
  label?: string;
}
//一级目录的select组件数据
const firstMenu = ref<optionIntface[]>([
]);

//对页面的操作属性
/**
 * 操作属性,查看是必须的，0只有查看权限，1增加，2修改，
 * 4删除，3增加修改，5增加删除，6修改删除，7增加修改删除
 */
const operation = ref<number>(0);
//从vuex中获得权限数据
const permissions = (store.state as StateAll).users.permission;
permissions.map((permission) => {
  permission.children?.map((second) => {
    const secondName = second.permissionName;
    //找到当前功能的权限数据，获得操作属性
    if (secondName == 'permission') {
      operation.value = second.operation;
      return;
    }
  });
});

//列表列属性定义
const columns = [
  {
    title: '目录名称',
    dataIndex: 'permissionName',
    key: 'permissionName',
  },
  {
    title: '显示名称',
    dataIndex: 'displayName',
    key: 'displayName'
  }
];

//目录对象数据类型定义，form组件使用
/**
 * id
 * pid 父id
 * permissionName 目录名称user,role等
 * displayName 显示名称，用户管理，角色管理等
 * description 描述
 * menuFlag 是否在目录中显示
 * orderNumber 同级目录顺序号
 */
interface FormState {
  id: number;
  pid?: number | optionIntface;
  permissionName: string;
  displayName: string;
  description?: string;
  menuFlag: boolean;
  patchString?: string;
  orderNumber: number;
}

//目录对象数据类型定义，table组件使用
/**
 *  children 子目录列表
 *  key 列表组件需要
 */
interface DataItem extends FormState {
  key: number;
  children?: DataItem[];
}
//列表数据变量
const tabledata: Ref<DataItem[]> = ref([]);
//列表选择的数据的key列表
const selectedRowKeys: Ref<number[]> = ref([]);
//列表选择的数据整行值列表
let selectionRows: DataItem[] = [];
//行点击事件,record参数为该行的整行值
const rowClick = (record: DataItem, index: number) => {
  return {
    //单击事件
    onClick: (event: MouseEvent) => {
      // const computedSelectedRowKeys = computed(() => selectedRowKeys.value)
      //   .value;
      //如果该行已经被选择，取消选择
      if (selectedRowKeys.value.includes(record.id)) {
        //过滤掉该行的key
        selectedRowKeys.value = selectedRowKeys.value.filter(function (
          val,
          index,
          arr
        ) {
          return val != record.id;
        });
        //过滤掉该行的数据整行值
        selectionRows = selectionRows.filter(function (
          val,
          index,
          arr
        ) {
          return val.id != record.id;
        });
      } else {
        //如果该行没有被选择，则进行选择，selectedRowKeys是响应数据，添加数据就是选择了行
        //由于是单选，所有需要先置空数据
        selectedRowKeys.value = [];
        selectedRowKeys.value.push(record.id);
        //选择的行的数据整行
        selectionRows = [];
        selectionRows.push(record);
        // console.log('push length'+selectionRows.value.length)
      }
    }
  };
};

//单击事件
const rowSelection = ref({
  hideDefaultSelections: true,
  selectedRowKeys,
  type: "radio",
  checkStrictly: false,
  onChange: (pselectedRowKeys: number[], pselectedRows: DataItem[]) => {
    // console.log("onchange---------------------------------")
    // console.log(`selectedRowKeys: ${pselectedRowKeys}`, 'selectedRows: ', pselectedRows);
    // console.log("onchange---------------------------------")
    selectedRowKeys.value = pselectedRowKeys;
    selectionRows = pselectedRows;
  }
  // onSelect: (record: DataItem, selected: boolean, selectedRows: DataItem[]) => {
  //   console.log("onSelect---------------------------------")
  //   console.log(record, selected, selectedRows);
  //   console.log("onSelect---------------------------------")
  // },
});
/**********新增**********/
//打开或关闭目录form窗口
const addOpen = ref<boolean>(false);
//窗口title
const addModifyTitle = ref<string>("新增目录");
//是否改动目录账号，新增时可修改，修改目录数据时，账号不能修改
const disabledFlag = ref<boolean>(false);
const formRef = ref();

//form中label宽度
const labelCol = { style: { width: '150px' } };
const wrapperCol = { span: 14 };

//form校验规则
const permissionRules = {
  pid: [
    {
      required: true,
      message: "一级目录必须选择！"
    }
  ],
  permissionName: [
    {
      required: true,
      message: "目录名称为必填项！",
      trigger: "blur",
    },
    {
      max: 20,
      message: "目录名长度不得超过20！",
      trigger: "blur",
    },
    {
      // 异步验证 多了一个callback函数
      validator: (rule: any, val: any, callback: any) => {

        if (val.length > 0) {
          const permissionnameParam = {
            permissionname: val,
            id: permission.id
          };
          // 这里进行异步操作,下面以promise举例
          http.get('/permission/validatePermissionname', permissionnameParam).then((res) => {
            if (res.data.status === "success") {
              callback()
            }
            else {
              callback(new Error('目录名称不能重复'))
            }
          })
        } else {
          callback()
        }
      },
      trigger: "blur"
    }
  ],
  displayName: [
    {
      required: true,
      message: "显示名称为必填项！",
      trigger: "blur",
    },
    {
      max: 20,
      message: "显示名称长度不得超过20！",
      trigger: "blur",
    }
  ],
  description: [
    {
      max: 20,
      message: "显示名称长度不得超过20！",
      trigger: "blur",
    }
  ],
  patchString: [
    {
      required: true,
      message: "权限匹配字符串为必填项！",
      trigger: "blur",
    },
    {
      max: 50,
      message: "权限匹配字符串长度不得超过50！",
      trigger: "blur",
    }
  ],

  orderNumber: [
    {
      required: true,
      message: "同级目录排序为必填项",
      trigger: "blur",
    },
    {
      pattern: /^\d{1,2}$/,
      message: '请输入正确数字',
      trigger: "blur",
    }
  ]
};


//目录对象数据变量定义
const permission: UnwrapRef<FormState> = reactive({
  id: 0,
  pid: 0,
  permissionName: "",
  displayName: "",
  description: "",
  menuFlag: true,
  patchString: "",
  orderNumber: 0
});

//重置目录对象数据
const clearPermission = () => {
  permission.id = 0;
  permission.pid = 0;
  permission.permissionName = "";
  permission.displayName = "";
  permission.description = "";
  permission.menuFlag = true;
  permission.patchString = "";
  permission.orderNumber = 0;
};
//设置目录对象数据
const setPermission = () => {
  permission.id = selectionRows[0].id;
  permission.pid = selectionRows[0].pid;
  permission.permissionName = selectionRows[0].permissionName;
  permission.displayName = selectionRows[0].displayName;
  permission.description = selectionRows[0].description;
  permission.menuFlag = selectionRows[0].menuFlag;
  permission.patchString = selectionRows[0].patchString;
  permission.orderNumber = selectionRows[0].orderNumber;
};
//关闭窗口
const closeForm = () => {
  //关闭窗口
  addOpen.value = false;
}

//窗口关闭后清除校验信息
const afterCloseModal = () => {
  formRef.value.clearValidate();
}

//增加一级目录按钮点击事件
const handleAddFirst = () => {
  //重置目录数据
  clearPermission();
  //修改title
  addModifyTitle.value = "新增一级目录";
  //一级目录不要一级目录和权限匹配字符串
  disabledFlag.value = false;
  //打开窗口
  addOpen.value = true;

};


//校验成功后提交form
const onFinish = (values: any) => {
  let url = '/permission/addPermission';
  //如果有pid则为二级目录，需要对pid做转换，由于select组件的缘故
  if (permission.pid && typeof permission.pid == 'object') {
    permission.pid = permission.pid.value;
  }
  //如果id不为0，则为修改数据，走修改数据的url
  if (permission.id != 0) {
    url = '/permission/modifyPermission';
  }

  http.post(url, permission).then((res) => {
    if (res.data.status === "success") {
      message.success("保存成功!");
      //关闭窗口
      addOpen.value = false;
      //执行查询公用方法
      executeQuery();
    }
    else {
      if (res.data.businessData.errMsg) {
        message.error(res.data.businessData.errMsg);
      } else {
        showErrors(res.data.businessData.errMsgList);
      }
    }
  })

};

const onFinishFailed = (errorInfo: any) => {
  console.log('Failed:', errorInfo);
};

/**********新增一级目录结束*********/
/**********新增二级目录*********/
//新增二级目录按钮点击事件
const handleAddSecond = () => {
  //重置目录数据
  clearPermission();
  //一级目录的select组件为未选择状态
  permission.pid = undefined;
  //修改title
  addModifyTitle.value = "新增二级目录";
  //二级目录需要显示选择一级目录和修改权限匹配字符串
  disabledFlag.value = true;
  //打开窗口
  addOpen.value = true;
};
/**********新增二级目录结束*********/

/**********修改目录*********/
const handleModify = () => {
  //如果选择了一条数据
  if (selectionRows.length == 1) {
    //设置角色数据
    setPermission();

    if (!permission.pid) {
      //设置窗口title
      addModifyTitle.value = "修改一级目录";
      //一级目录不需要修改一级目录,patchString等
      disabledFlag.value = false;
    } else {
      //设置窗口title
      addModifyTitle.value = "修改二级目录";
      //二级目录需要修改一级目录,patchString等
      disabledFlag.value = true;
      //找到相对应的option数据
      const menu = firstMenu.value.filter(m => m.value == permission.pid)
      //赋值给select组件
      permission.pid = menu[0];
    }
    //打开窗口
    addOpen.value = true;
  } else {
    message.info("请选择一条数据!");
  }
};
/**********修改目录结束*********/

/********删除**********/
//删除提示框显示变量
const deleteOpen = ref<boolean>(false);
//目录关联了角色，确认model提示框显示变量
const deleteConfirmOpen = ref<boolean>(false);

//删除按钮点击事件
const handleDelete = () => {
  //判断是否选择了数据
  if (selectedRowKeys.value.length == 0) {
    message.info("请选择数据");
    return;
  }
  //显示删除数据提示框
  deleteOpen.value = true;
};

//确定删除
const deleteOk = () => {
  //关闭提示框
  deleteOpen.value = false;
  //要删除的数据参数
  const deleteParam = {
    id: selectedRowKeys.value[0]
  }
  //查看目录是否被角色关联
  http.get('/permission/findRoleCountByPermissionId', deleteParam).then((res) => {
    if (res.data.status === "success") {
      const result = res.data.businessData;
      //有关联的角色
      if (result > 0) {
        deleteConfirmOpen.value = true;
      } else {
        //没有关联的橘色，执行删除
        executePermissionDelete();
      }
    }
    else {
      message.error(res.data.businessData.errMsg);
    }
  });
};


//确定删除
const deleteConfirmOk = () => {
  //关闭提示框
  deleteConfirmOpen.value = false;
  executePermissionDelete();
};

//执行删除目录
const executePermissionDelete = () => {
  //要删除的数据参数

  //删除
  http.delete('/permission/delete', selectedRowKeys.value).then((res) => {
    if (res.data.status === "success") {
      //执行查询公用方法
      executeQuery();
    }
    else {
      message.error(res.data.businessData.errMsg);
    }
  })
}

//执行查询公用方法
const executeQuery = () => {
  http.get('/permission/getAllPermission').then((res) => {
    if (res.data.status === "success") {
      tabledata.value = res.data.businessData;
      //查询结束后，初始化一级目录select组件的数据
      firstMenu.value = [];
      tabledata.value.map(m =>
        firstMenu.value?.push(
          {
            value: m.id,
            label: m.displayName
          }
        )
      )
    }
    else {
      message.error(res.data.businessData.errMsg);
    }
  })
  //重置key值的数组
  selectedRowKeys.value = [];
  //重置选择的数据值的数组
  selectionRows = [];
}
//页面加载完成后，刷新第一页数据
onMounted(() => {
  //执行查询公用方法
  executeQuery();
});
</script>

  
  